﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using PPI.Client.Interface;
using PPI.Client.Logic.Delegate;
using PPI.Client.Logic.Inspection;
using PPI.Client.Utils;
using PPI.Entities.Inspections;

namespace PPI.Client.Presenter
{
    public class EditStructurePresenter
    {
        private IEditStructure m_view;
        private List<Int32> m_PassedInspections;
        private List<EInspection> m_AddedInspections;
        private BackgroundWorker m_Worker;
        private UpdateBar m_delegateUpdateBar;
        private UpdateMessage m_delegateMessage;

        public EditStructurePresenter(IEditStructure view)
        {
            this.m_view = view;
            Initilize();
        }

        private void Initilize()
        {
            try
            {
                m_delegateMessage = new UpdateMessage(updateMessageProcess);
                m_delegateUpdateBar = new UpdateBar(updateProcessBar);
                m_Worker = new BackgroundWorker();
                m_Worker.DoWork += new DoWorkEventHandler(m_Worker_DoWork);
                m_Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_Worker_RunWorkerCompleted);
                m_AddedInspections = new List<EInspection>();
                m_AddedInspections.Add(m_view.InspectionResult.Inspection);
            }
            catch(Exception ex)
            {
                RegisterError.SaveError(ex);
            }
        }

        private void updateMessageProcess(string message)
        {
            m_view.MessageProgress = message;
        }

        private void updateProcessBar(int percentage)
        {
            m_view.ProcessProgress = percentage;
        }

        void m_Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            m_view.SearchedInspections = m_AddedInspections;
            m_view.AddInspections();
        }

        void m_Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            SearchInspections();
        }

        protected void SearchInspections()
        {
            bool isAddedNewInspection = false;
            int counterInspections = 1;
            List<EInspection> m_tempListInspections = new List<EInspection>();
            foreach (EInspectionResult projectInspection in m_view.InpectionResults)
            {
                if (!m_AddedInspections.Contains(projectInspection.Inspection))
                {
                    updateMessageProcess(string.Format("Inspection {0}", projectInspection.Inspection.Id));
                    foreach (EInspection addedInspection in m_AddedInspections)
                    {
                        m_delegateUpdateBar((counterInspections*100)/m_AddedInspections.Count);
                        if (GeoHelper.GetDistanceBetweenCoordinates(addedInspection.Latitude, addedInspection.Longitude, projectInspection.Inspection.Latitude, projectInspection.Inspection.Longitude) <= 5)
                        {
                            isAddedNewInspection = true;
                            m_tempListInspections.Add(projectInspection.Inspection);
                        }
                        counterInspections++;
                    }
                }

            }

            foreach (EInspection inspection in m_tempListInspections)
            {
                if(!m_AddedInspections.Contains(inspection))
                    m_AddedInspections.Add(inspection);
            }

            if(isAddedNewInspection)
                SearchInspections();
        }

        public void StartSearchInspection()
        {
            m_Worker.RunWorkerAsync();
        }

        protected EInspection FindInspection(Int32 inspectionId)
        {
            EInspectionResult foundInspectionResult = m_view.InpectionResults.Find(delegate(EInspectionResult r) { return r.Inspection.Id == inspectionId; });
            if(foundInspectionResult != null)
                return foundInspectionResult.Inspection;
            else
                return null;
        }

        public void AddInspection(Int32 inspectionId)
        {
            EInspection tmpInspection = FindInspection(inspectionId);
            if(tmpInspection != null)
            {
                if(!m_AddedInspections.Contains(tmpInspection))
                    m_AddedInspections.Add(tmpInspection);
            }
            m_view.SearchedInspections = m_AddedInspections;
            m_view.AddInspections();
            m_view.ShowNewAutodeterminate();
        }

        public void Save()
        {
            try
            {
                LInspection.CreateVisit(m_view.InspectionResult.Inspection, m_AddedInspections);
            }
            catch(Exception ex)
            {
                RegisterError.SaveError(ex);
            }
            
        }
    }
}
